package com.xm.httpapi.BaseApi;

import com.google.gson.Gson;
import com.google.gson.JsonIOException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.xm.httpapi.BaseApiStatus.ErrorType;
import com.xm.httpapi.BaseApiStatus.ServerException;
import com.xm.httpapi.BaseApiStatus.TokenInvalidException;
import com.xm.httpapi.BaseUtils.LogUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Iterator;
import okhttp3.MediaType;
import okhttp3.ResponseBody;
import retrofit2.Converter;

import static okhttp3.internal.Util.UTF_8;

/**
 *
 */

public class CustomGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
    private final Gson gson;
    private final TypeAdapter<T> adapter;

    CustomGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
        this.gson = gson;
        this.adapter = adapter;
    }

    @Override
    public T convert(ResponseBody value) throws IOException {
        try {
            String response = value.string();
            LogUtils.e("convert: " + response);
            JSONObject mJSONObject = null;
            try {
                mJSONObject = new JSONObject(response);
            } catch (JSONException mE) {
                mE.printStackTrace();
                value.close();
                throw new ServerException(ErrorType.EMPTY_BEAN.getCode(), ErrorType.EMPTY_BEAN.getMessage());
            }
            Iterator<String> iterator = mJSONObject.keys();
            String ReponseCodeName = "", ReponseMessageName = "";
            while (iterator != null && iterator.hasNext()) {
                String name = iterator.next();
                if (name.equals("code") || name.equals("statusCode")) {
                    ReponseCodeName = name;
                } else if (name.equals("message") || name.equals("Msg") || name.equals("msg") || name.equals("error")
                        || name.equals("err") || name.equals("errorMsg") || name.equals("errorMessage")) {
                    ReponseMessageName = name;
                }
            }
            int code = mJSONObject.optInt(ReponseCodeName, -1);
            if (code == BaseApi.ReponseSucessCode) {
                MediaType mediaType = value.contentType();
                Charset charset = mediaType != null ? mediaType.charset(UTF_8) : UTF_8;
                InputStream inputStream = new ByteArrayInputStream(response.getBytes());
                JsonReader jsonReader = gson.newJsonReader(new InputStreamReader(inputStream, charset));
                T result = adapter.read(jsonReader);
                if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
                    value.close();
                    throw new JsonIOException("JSON document was not fully consumed.");
                }
                return result;
            } else if (code == BaseApi.ReponseTokenInvalidCode) {
                String message = mJSONObject.optString(ReponseMessageName);
                value.close();
                throw new TokenInvalidException(code,message);
            } else {
                String message = mJSONObject.optString(ReponseMessageName);
                value.close();
                throw new ServerException(code, message);
            }
        } finally {
            value.close();
        }
    }
}
